﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Shell.PocoDot
{
    /// <summary>
    /// 表示一个数据上下文, 此数据上下文封装了对一种特定的 PocoDot 的 CRUD 操作
    /// </summary>
    /// <typeparam name="TPocoDot"></typeparam>
    public interface IDataContext<TPocoDot> : IPersistent, IDisposable
        where TPocoDot : PocoDotBase
    {
        /// <summary>
        /// 创建一个具有默认值的 PocoDot
        /// </summary>
        /// <returns>该操作创建的新的 PocoDot 实例</returns>
        /// <remarks>此变更将挂起, 在提交变更时该数据会被存入持久化层</remarks>
        TPocoDot Create();

        /// <summary>
        /// 添加特定的 PocoDot
        /// </summary>
        /// <param name="dot">特定的 PocoDot, 其 Identity 会被重新生成</param>
        /// <returns>已被添加的该特定的 PocoDot 实例</returns>
        /// <remarks>此变更将挂起, 在提交变更时该数据会被存入持久化层</remarks>
        TPocoDot Add(TPocoDot dot);

        /// <summary>
        /// 更新特定的 PocoDot
        /// </summary>
        /// <param name="dot">特定的 PocoDot, 其 Identity 会被作为标识从持久化层查询, 其他值将被更新</param>
        /// <returns>已被更新的该特定的 PocoDot 实例</returns>
        /// <remarks>此变更将挂起, 在提交变更时该数据会被存入持久化层</remarks>
        /// <exception cref="System.InvalidOperationException">指定的 Identity 在持久化层查到多条数据</exception>
        /// <exception cref="System.InvalidOperationException">当前实例已被销毁</exception>
        /// <exception cref="System.InvalidOperationException">无法查询到指定的 Identity 的实例</exception>
        TPocoDot Update(TPocoDot dot);

        /// <summary>
        /// 读取持久化层中存储的所有实例
        /// </summary>
        /// <returns>该特定实例的集合</returns>
        /// <remarks>返回的结果中包含已被挂起的数据</remarks>
        IQueryable<TPocoDot> Read();

        /// <summary>
        /// 读取持久化层中存储的特定实例集合
        /// </summary>
        /// <param name="keys">将要读取的特定实例的标识集合</param>
        /// <returns>该特定实例的集合</returns>
        /// <remarks>返回的结果中包含已被挂起的数据</remarks>
        /// <exception cref="System.ArgumentNullException">参数为空引用</exception>
        IQueryable<TPocoDot> Read(IEnumerable<Guid> keys);

        /// <summary>
        /// 读取持久化层中存储的特定实例
        /// </summary>
        /// <param name="key">将要读取的特定实例的标识</param>
        /// <returns>该特定实例</returns>
        /// <remarks>返回的结果中包含已被挂起的数据</remarks>
        /// <exception cref="System.InvalidOperationException">指定的 Identity 在持久化层查到多条数据</exception>
        /// <exception cref="System.InvalidOperationException">当前实例已被销毁</exception>
        TPocoDot Read(Guid key);

        /// <summary>
        /// 删除持久化层中存储的特定实例
        /// </summary>
        /// <param name="key">将要删除的特定实例的标识</param>
        /// <remarks>操作的数据会包含已被挂起的数据</remarks>
        /// <exception cref="System.InvalidOperationException">指定的 Identity 在持久化层查到多条数据</exception>
        /// <exception cref="System.InvalidOperationException">当前实例已被销毁</exception>
        /// <exception cref="System.InvalidOperationException">无法查询到指定的 Identity 的实例</exception>
        void Delete(Guid key);
    }
}
